﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.CompilerServices;

namespace CygwinPackageManager.Common
{
	public class PackageCategoryDALC
	{
		public IEnumerable<PackageCategory> GetCategories()
		{
			return Categories;
		}
		
		public int GetCategoryID(string categoryName)
		{
			return _GetCategoryID(categoryName);
		}

		private static IEnumerable<PackageCategory> _categories;
		private static IEnumerable<PackageCategory> Categories
		{
			[MethodImpl(MethodImplOptions.Synchronized)]
			get
			{
				if (_categories == null)
					_categories = _GetCategories();

				return _categories;
			}
		}

		[MethodImpl(MethodImplOptions.Synchronized)]
		private static IEnumerable<PackageCategory> _GetCategories()
		{
			List<PackageCategory> categories = new List<PackageCategory>();
			foreach (string categoryName in (new AvailablePackageDALC()).GetAvailablePackages().SelectMany(p => p.Categories))
			{
				int categoryID = _GetCategoryID(categoryName);
				if (categories.FirstOrDefault(c => c.PackageCategoryID == categoryID) == null)
				{
					categories.Add(new PackageCategory()
					{
						Name = categoryName,
						PackageCategoryID = categoryID,
						IsSpecial = categoryName.StartsWith("_"),
					});
				}
			}

			return categories;
		}

		private static Dictionary<string, int> _categoryIDs;
		private static Dictionary<string, int> CategoryIDs
		{
			[MethodImpl(MethodImplOptions.Synchronized)]
			get
			{
				if (_categoryIDs == null)
					_categoryIDs = new Dictionary<string, int>();

				return _categoryIDs;
			}
		}

		[MethodImpl(MethodImplOptions.Synchronized)]
		private static int _GetCategoryID(string categoryName)
		{
			Dictionary<string, int> categoryIDs = CategoryIDs;
			int categoryID = 0;
			lock (categoryIDs)
			{
				if (categoryIDs.Count == 0)
				{
					categoryID = 1;
					categoryIDs.Add(categoryName, categoryID);
				}
				if (!categoryIDs.ContainsKey(categoryName))
				{
					categoryID = categoryIDs.Values.Max() + 1;
					categoryIDs.Add(categoryName, categoryID);
				}
				else
				{
					categoryID = categoryIDs[categoryName];
				}
			}

			return categoryID;
		}
	}
}
